﻿namespace Minesweeper
{
    using System;
    using System.Threading;

    class ConsoleDrawer
    {
        public static void HighlightCell(int currentX, int currentY)
        {
            Console.SetCursorPosition(currentX, currentY);
            Cell.DrawOnlyFrame(currentX, currentY, ConsoleColor.Green);
            Console.SetCursorPosition(currentX, currentY);
        }

        public static void UnHighLightCell(int currentX, int currentY)
        {
            Console.SetCursorPosition(currentX, currentY);
            Cell.DrawOnlyFrame(currentX, currentY, ConsoleColor.Black);
            Console.SetCursorPosition(currentX, currentY);
        }

        public static void DrawOpenedBlock(int currentX, int currentY, ConsoleColor color, int row = -1, int col = -1, bool recursiveCall = false)
        {
            if (row == -1 && col == -1)
            {
                row = MinesweeperGame.playField.CurrentRow;
                col = MinesweeperGame.playField.CurrentCol;
            }

            Cell cell = MinesweeperGame.playField[row, col];
            currentX = cell.X;
            currentX = cell.Y;

            if (cell.IsMine)
            {
                cell.Draw(Cell.Mine, -1, ConsoleColor.Red, true);
                Thread.Sleep(500);
                PrintLosingMessage();
            }
            else if (cell.Content == 0)
            {
                cell.Visit();
                cell.Draw(Cell.ZeroBlock, color: color, recursiveCall: recursiveCall);
                for (int deltaRow = -1; deltaRow <= 1; deltaRow++)
                {
                    for (int deltaCol = -1; deltaCol <= 1; deltaCol++)
                    {
                        if (deltaRow == 0 && deltaCol == 0)
                        {
                            continue;
                        }

                        if (MinesweeperGame.playField.IsInMatrix(row + deltaRow, col + deltaCol) &&
                            !MinesweeperGame.playField[row + deltaRow, col + deltaCol].IsVisited &&
                            !MinesweeperGame.playField[row + deltaRow, col + deltaCol].IsFlagged)
                        {
                            OpenCell(-1, -1, row + deltaRow, col + deltaCol, true);
                        }
                    }
                }

                if (!recursiveCall)
                {
                    HighlightCell(cell.X, cell.Y);
                }
            }
            else if (cell.Content == 1)
            {
                cell.Draw(Cell.OneBlock, 1, color, recursiveCall: recursiveCall);
            }
            else if (cell.Content == 2)
            {
                cell.Draw(Cell.TwoBlock, 2, color, recursiveCall: recursiveCall);
            }
            else if (cell.Content == 3)
            {
                cell.Draw(Cell.ThreeBlock, 3, color, recursiveCall: recursiveCall);
            }
            else if (cell.Content == 4)
            {
                cell.Draw(Cell.FourBlock, 4, color, recursiveCall: recursiveCall);
            }
            else if (cell.Content == 5)
            {
                cell.Draw(Cell.FiveBlock, 5, color, recursiveCall: recursiveCall);
            }
            else if (cell.Content == 6)
            {
                cell.Draw(Cell.SixBlock, 6, color, recursiveCall: recursiveCall);
            }
            else if (cell.Content == 7)
            {
                cell.Draw(Cell.SevenBlock, 7, color, recursiveCall: recursiveCall);
            }
            else if (cell.Content == 8)
            {
                cell.Draw(Cell.EightBlock, 8, color, recursiveCall: recursiveCall);
            }
        }

        // Returns true if the opened cell is a mine. Useful when checking for mines on initial click
        public static bool OpenCell(int currentX, int currentY, int row = -1, int col = -1, bool recursiveCall = false)
        {
            bool isMine = false;

            if (row == -1 && col == -1)
            {
                row = MinesweeperGame.playField.CurrentRow;
                col = MinesweeperGame.playField.CurrentCol;
                isMine = MinesweeperGame.playField.CurrentCell.IsMine;
            }
            else
            {
                Cell cell = MinesweeperGame.playField[row, col];
                currentX = cell.X;
                currentY = cell.Y;
                isMine = cell.IsMine;
            }

            Console.SetCursorPosition(currentX, currentY);
            DrawOpenedBlock(currentX, currentY, ConsoleColor.Green, row, col, recursiveCall);
            MinesweeperGame.playField.Visit(row, col);
            Console.SetCursorPosition(currentX, currentY);

            return isMine;
        }

        public static void PlaceOrRemoveFlag(int currentX, int currentY)
        {
            Cell cell = MinesweeperGame.playField[MinesweeperGame.playField.CurrentRow, MinesweeperGame.playField.CurrentCol];
            currentX = cell.X;
            currentY = cell.Y;

            if (cell.IsFlagged)
            {
                cell.RemoveFlag();
                Console.SetCursorPosition(currentX, currentY);
                if (!MinesweeperGame.playField.CurrentCell.IsVisited)
                {
                    MinesweeperGame.playField.CurrentCell.Draw(Cell.NotOpenedBlock, -1, ConsoleColor.Green, false);
                }
                Console.SetCursorPosition(currentX, currentY);
            }
            else
            {
                cell.PlaceFlag();
                Console.SetCursorPosition(currentX, currentY);
                if (!MinesweeperGame.playField.CurrentCell.IsVisited)
                {
                    MinesweeperGame.playField.CurrentCell.Draw(Cell.Flag, -1, ConsoleColor.Green, true);
                }
                Console.SetCursorPosition(currentX, currentY);
            }
        }

        public static void WinGame()
        {
            MinesweeperGame.timer.Dispose();
            var oldForeGroundColor = Console.ForegroundColor;
            Console.Clear();
            Console.BackgroundColor = ConsoleColor.Black;
            Console.ForegroundColor = ConsoleColor.Red;
            Menu.SetConsoleForMenu();
            string[] youWin = 
            {
                @"_____.___.               __      __.__        ",
                @"\__  |   | ____  __ __  /  \    /  \__| ____  ",
                @" /   |   |/  _ \|  |  \ \   \/\/   /  |/    \ ",
                @" \____   (  <_> )  |  /  \        /|  |   |  \",
                @" / ______|\____/|____/    \__/\  / |__|___|  /",
                @" \/                            \/          \/ ",
            };
            int posX = (Console.WindowWidth / 2) - (youWin[0].Length / 2);
            int posY = (Console.WindowHeight / 2) - youWin.Length;
            for (int element = 0; element < youWin.Length; element++)
            {
                Console.SetCursorPosition(posX, posY);
                Console.Write(youWin[element]);
                posY++;
            }
            posY++;
            posX = (Console.WindowWidth / 2) - 12;
            Console.SetCursorPosition(posX, posY);
            Console.Write("Please enter your name:");
            MinesweeperGame.playerName = Console.ReadLine();
            HighScores.NewScore(MinesweeperGame.seconds, MinesweeperGame.playerName);
            if (MinesweeperGame.ContinueGame(posY))
            {
                Console.ForegroundColor = oldForeGroundColor;
                MinesweeperGame.NewGame = true;
                MinesweeperGame.ResetGameStatusAndContinue();
            }
            else
            {
                Console.ForegroundColor = oldForeGroundColor;
                Environment.Exit(0);
            }
        }

        public static void PrintLosingMessage()
        {
            MinesweeperGame.timer.Dispose();
            var oldForeGroundColor = Console.ForegroundColor;
            Console.Clear();
            Console.BackgroundColor = ConsoleColor.Black;
            Console.ForegroundColor = ConsoleColor.Red;
            Menu.SetConsoleForMenu();
            string[] losingMessage = 
			{
				@"_____ ___                __                     ",
                @"\__  |   | ____  __ __  |  |    ____  ___   ___ ",
                @" /   |   |/  _ \|  |  \ |  |   /  _ \/ __| / _ \",
                @" \____   (  <_> )  |  / |  |  (  <_> \__ \|  __/",
                @" / ______|\____/|____/  |  |__ \____/|___/ \___|",
                @" \/                     |_____|                 ",
			};

            int posX = (Console.WindowWidth / 2) - (losingMessage[0].Length / 2);
            int posY = (Console.WindowHeight / 2) - losingMessage.Length;
            for (int element = 0; element < losingMessage.Length; element++)
            {
                Console.SetCursorPosition(posX, posY);
                Console.Write(losingMessage[element]);
                posY++;
            }
            posY++;
            Console.SetCursorPosition(posX, posY);

            if (MinesweeperGame.ContinueGame(posY))
            {
                MinesweeperGame.NewGame = false;
            }
            else
            {
                MinesweeperGame.NewGame = true;
            }

            Console.ForegroundColor = oldForeGroundColor;
            Console.Clear();
            MinesweeperGame.ResetGameStatusAndContinue();
        }
    }
}
